package vn.edu.ptithcm.pim.dao;

import vn.edu.ptithcm.pim.dom.Role;
import vn.edu.ptithcm.pim.dom.User;
import vn.edu.ptithcm.pim.service.SpringSercurityService;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.LockMode;
import org.hibernate.Transaction;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

@SuppressWarnings({ "rawtypes" })
public class UserDao extends HibernateDaoSupport {
	private SpringSercurityService springSercurityService;

	public void save(User user) {
		try {
			Transaction tx = getSession().beginTransaction();
			getHibernateTemplate().save(user);
			tx.commit();
		} catch (RuntimeException re) {
			throw re;
		}
	}

	public void saveOrUpdate(User user) {
		try {
			Transaction tx = getSession().beginTransaction();
			getHibernateTemplate().saveOrUpdate(user);
			tx.commit();
		} catch (RuntimeException re) {
			throw re;
		}
	}

	public void lock(User user) {
		try {
			Transaction tx = getSession().beginTransaction();
			getHibernateTemplate().lock(user, LockMode.NONE);
			tx.commit();
		} catch (RuntimeException re) {
			throw re;
		}
	}

	public void delete(User user) {
		try {
			Transaction tx = getSession().beginTransaction();
			getHibernateTemplate().delete(user);
			tx.commit();
		} catch (RuntimeException re) {
			throw re;
		}
	}

	public User merge(User user) {
		try {
			return (User) getHibernateTemplate().merge(user);
		} catch (RuntimeException re) {
			throw re;
		}
	}

	public User findById(java.lang.Long id) {
		try {
			return (User) getHibernateTemplate().get(User.class, id);
		} catch (RuntimeException re) {
			throw re;
		}
	}

	public List findByExample(User user) {
		try {
			return getHibernateTemplate().findByExample("User", user);
		} catch (RuntimeException re) {
			throw re;
		}
	}

	public List getAll() {
		try {
			return getHibernateTemplate().loadAll(User.class);
		} catch (RuntimeException re) {
			throw re;
		}
	}

	public User findByLoginName(String loginname) {
		try {
			StringBuilder sql = new StringBuilder();
			sql.append("from User as user where user.loginname = '")
					.append(loginname).append("'");
			List result = getHibernateTemplate().find(sql.toString());
			return (result != null && result.size() == 1) ? (User) result
					.get(0) : null;
		} catch (RuntimeException re) {
			throw re;
		}
	}

	public User findByEmail(String email) {
		try {
			StringBuilder sql = new StringBuilder();
			sql.append("from User as user where user.email = '").append(email)
					.append("'");
			List result = getHibernateTemplate().find(sql.toString());
			return (result != null && result.size() == 1) ? (User) result
					.get(0) : null;
		} catch (RuntimeException re) {
			throw re;
		}
	}

	public boolean isLogin(String loginname, String password, Object salt) {
		try {
			User user = findByLoginName(loginname);
			return springSercurityService.isPasswordValid(user.getPassword(),
					password, salt);
		} catch (RuntimeException re) {
			throw re;
		}
	}

	public boolean isAdmin(String loginname) {
		try {
			User user = findByLoginName(loginname);
			return user != null && user.getRole().getRoleid() == 1 ? true
					: false;
		} catch (RuntimeException re) {
			throw re;
		}
	}

	public String getUsername(String loginname) {
		try {
			User user = findByLoginName(loginname);
			return user != null ? user.getEmployee().getLastname() + " "
					+ user.getEmployee().getFirstname() : " ";
		} catch (RuntimeException re) {
			throw re;
		}
	}

	public String getVisa(String loginname) {
		try {
			User user = findByLoginName(loginname);
			return user != null ? user.getEmployee().getVisa() : " ";
		} catch (RuntimeException re) {
			throw re;
		}
	}

	public List getApplications(String loginname) {
		try {
			User user = findByLoginName(loginname);
			if (user != null) {
				StringBuilder sql = new StringBuilder();
				Role role = user.getRole();
				sql.append("select rap.application ")
						.append("from RoleApplicationPermission as rap ")
						.append("where rap.role.roleid = '")
						.append(role.getRoleid())
						.append("' order by rap.application.applicationid");
				getHibernateTemplate().setMaxResults(10);
				return getHibernateTemplate().find(sql.toString());
			}
			return new ArrayList(0);
		} catch (RuntimeException re) {
			throw re;
		}
	}

	public int getPermisionOfUserInApplication(String loginname,
			java.lang.Long applicationId) {
		try {
			User user = findByLoginName(loginname);
			if (user != null) {
				StringBuilder sql = new StringBuilder();
				Role role = user.getRole();
				sql.append("select rap.permission ")
						.append("from RoleApplicationPermission as rap ")
						.append("where rap.role.roleid = '")
						.append(role.getRoleid()).append("' ")
						.append(" and rap.application.applicationid = '")
						.append(applicationId).append("'");
				List result = getHibernateTemplate().find(sql.toString());
				if (result != null && result.size() == 1) {
					return Integer.parseInt(result.get(0).toString());
				}
			}
			return -1;
		} catch (RuntimeException re) {
			throw re;
		}
	}

	public boolean changePassword(String loginName, String oldPass,
			String newPass, Object salt) {
		boolean isSuccess = true;
		User user = findByLoginName(loginName);
		if (user != null) {
			String encPass = springSercurityService.encodePassword(oldPass,
					salt);
			if (encPass.equals(user.getPassword())) {
				user.setPassword(springSercurityService.encodePassword(newPass,
						salt));
				saveOrUpdate(user);
			} else {
				isSuccess = false;
			}
		} else {
			isSuccess = false;
		}
		return isSuccess;
	}

	public String resetPassword(String email, Object salt) {
		String newPass = "";
		User user = findByEmail(email);
		if (user != null) {
			newPass = springSercurityService.getPasswordGenerator().generate();
			user.setPassword(springSercurityService.encodePassword(newPass,
					salt));
			saveOrUpdate(user);
		}
		return newPass;
	}

	public SpringSercurityService getSpringSercurityService() {
		return springSercurityService;
	}

	public void setSpringSercurityService(
			SpringSercurityService springSercurityService) {
		this.springSercurityService = springSercurityService;
	}
}
